import cv2
import numpy as np
import matplotlib.pyplot as plt

def sobel_edge_detection(image_path):
    """
    对输入图像进行Sobel边缘检测和形态学操作
    
    Args:
        image_path: 图像路径
    
    Returns:
        edges: 边缘检测结果
        gray: 灰度图像
    """
    # 读取图像
    img = cv2.imread(image_path)
    if img is None:
        raise ValueError(f"无法读取图像: {image_path}")
    
    # 转换为灰度图
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    # 高斯模糊
    blurred = cv2.GaussianBlur(gray, (5, 5), 0)
    
    # Sobel边缘检测
    sobelx = cv2.Sobel(blurred, cv2.CV_64F, 1, 0, ksize=3)
    sobely = cv2.Sobel(blurred, cv2.CV_64F, 0, 1, ksize=3)
    
    # 计算边缘强度
    edges = np.sqrt(sobelx**2 + sobely**2)
    
    # 归一化到0-255
    edges = np.uint8(edges * 255 / np.max(edges))
    
    # 形态学操作
    kernel = np.ones((3,3), np.uint8)
    edges = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel)  # 闭运算填充小孔
    edges = cv2.morphologyEx(edges, cv2.MORPH_OPEN, kernel)   # 开运算去除小噪点
    
    return edges, gray

def compare_images(image1_path, image2_path):
    """
    比较两幅图像的边缘检测结果
    
    Args:
        image1_path: 第一幅图像路径
        image2_path: 第二幅图像路径
    """
    # 对两幅图像进行边缘检测
    edges1, gray1 = sobel_edge_detection(image1_path)
    edges2, gray2 = sobel_edge_detection(image2_path)
    
    # 确保两幅图像大小相同
    if edges1.shape != edges2.shape:
        raise ValueError("两幅图像大小不一致")
    
    # 计算边缘检测结果的差异
    diff = cv2.absdiff(edges1, edges2)
    
    # 计算差异度量
    total_pixels = edges1.shape[0] * edges1.shape[1]
    different_pixels = np.count_nonzero(diff)
    similarity = 1 - (different_pixels / total_pixels)
    
    # 显示结果
    plt.figure(figsize=(15, 10))
    
    plt.subplot(231)
    plt.imshow(gray1, cmap='gray')
    plt.title('src1')
    
    plt.subplot(232)
    plt.imshow(gray2, cmap='gray')
    plt.title('src2')
    
    plt.subplot(233)
    plt.imshow(diff, cmap='gray')
    plt.title('diff')
    
    plt.subplot(234)
    plt.imshow(edges1, cmap='gray')
    plt.title('Sobel edge1')
    
    plt.subplot(235)
    plt.imshow(edges2, cmap='gray')
    plt.title('Sobel edge2')
    
    plt.subplot(236)
    plt.text(0.5, 0.5, f'similarity: {similarity:.2%}\n' +
             f'diff pixels: {different_pixels}',
             horizontalalignment='center',
             verticalalignment='center',
             fontsize=12)
    plt.axis('off')
    
    plt.tight_layout()
    plt.show()

if __name__ == "__main__":
    image1_path = "image1.jpg"
    image2_path = "image3.jpg"
    
    compare_images(image1_path, image2_path)
